import java.util.ArrayList;
import java.util.BitSet;
import java.util.Hashtable;
import java.util.LinkedList;

import Blocks.Block;
import Blocks.NextState;


public class TreeRules 
{
        private Hashtable<BitSet , BitSet> previousBlocks;
        private ArrayList<BitSet> positions;
        
 
        public TreeRules()
        {
                previousBlocks = new Hashtable<BitSet, BitSet>();
                positions = new ArrayList<BitSet>();
        }
        
        public boolean applyRule1 (Block currentBlock)
        {
                LinkedList<NextState> states = currentBlock.getNode();
                for(int i=0;i<states.size();i++)
                {
                        NextState currentState = states.get(i);
                        String elements = currentState.getNextState().toString();
                        if(elements.length()-2!=1)
                        {
                                return  false;
                        }
                }
                return true;
        }

        public boolean applyRule2 (Block currentBlock,int index)
        {
                boolean x= true;
                LinkedList<NextState> states = currentBlock.getNode();
                for(int i=0;i<states.size();i++)
                {
                        NextState currentState = states.get(i);
                        BitSet elements = currentState.getNextState();
                        if(previousBlocks.containsKey(elements))
                        {
                                BitSet blocksHaveSameParts = previousBlocks.get(elements);
                                blocksHaveSameParts.set(index);
                                positions.add(elements);
                                previousBlocks.put(elements, blocksHaveSameParts);
                        }
                        else
                        {
                                BitSet blockParts = new BitSet();
                                blockParts.set(index);
                                previousBlocks.put(elements, blockParts);
                                x= false;
                        }
                }
                if(!x && positions.size()!=0)
                {
                        BitSet first = positions.get(0);
                        BitSet required = previousBlocks.get(first);
                        int i=1;
                        while(i<positions.size()&&(!first.isEmpty())){
                                required.and( previousBlocks.get(positions.get(i)));
                                i++;
                        }
                        if(required.isEmpty())
                        {
                                x= false;
                        }       
                }
                return x;
        }

        public void init()
        {
                positions = new ArrayList<BitSet>();
        }
        
        
//      public boolean  setBlocks (BitSet blockBitSet ,int index )
//      {
//              
//              if(previousBlocks.containsKey(blockBitSet))
//              {
//                      BitSet blocksHaveSameParts = (BitSet) previousBlocks.get(blockBitSet).clone();
//                      positions.add(blockBitSet);
//                      blocksHaveSameParts.set(index);
//                      previousBlocks.put(blockBitSet, blocksHaveSameParts);
//                      return true;
//              }
//              else
//              {
//                      BitSet blocksHaveSameParts = new BitSet();
//                      blocksHaveSameParts.set(index);
//                      previousBlocks.put(blockBitSet,blocksHaveSameParts);
//                      return false;
//              }
//      }
//
//      public boolean checkRule2 ()
//      {
//              // true rule2 is satisfied
//              if(positions.size()==0){
//                      return false;
//              }
//              BitSet first = positions.get(0);
////            System.out.println("first"+first);
//              BitSet required = previousBlocks.get(first);
////            System.out.println("req"+required.toString());
//              int i=1;
//              while(i<positions.size()&&(!first.isEmpty())){
////                    System.out.println("size"+positions.size());
////                    System.out.println("index"+i);
//                      required.and( previousBlocks.get(positions.get(i)));
////                    System.out.println("pos"+positions.get(i));
////                    System.out.println("pre"+previousBlocks.get(positions.get(i)));
////                    System.out.println("req2"+required);
//                      i++;
//              }
//              String bitSetElements = required.toString();
//               int length = bitSetElements.length()-2;
//              if(first.isEmpty())
//              {
//                      return false;
//              }
//              else if(length>2){
//                      
//                      System.out.println("Wrong");
//              }
//              return true;
//      }
//      
//      
//      public void init()
//      {
//              positions = new ArrayList<BitSet>();
//      }
//      
//      public Hashtable<BitSet, BitSet> getPreviousBlocks() {
//              return previousBlocks;
//      }
//
//      public void setPreviousBlocks(Hashtable<BitSet, BitSet> previousBlocks) {
//              this.previousBlocks = previousBlocks;
//      }
//      
//      public static void main(String[] args) {
//               Hashtable<BitSet , BitSet> previousBlocks = new Hashtable<BitSet, BitSet>();
//               BitSet x = new BitSet();
//               x.set(1);
//               x.set(2);
//               BitSet x1 = new BitSet();
//               x1.set(1);
//               x1.set(3);
//               BitSet x2 = new BitSet();
//               x2.set(1);
//               x2.set(4);
//               BitSet m = new BitSet();
//               m.set(1);
//               m.set(2);
//               BitSet m1 = new BitSet();
//               m1.set(1);
//               m1.set(3);
//               previousBlocks.put(x,m);
//               previousBlocks.put(x1, m1);
//               TreeRules k = new  TreeRules();
//               k.setPreviousBlocks(previousBlocks);
//
//               System.out.println(k.setBlocks(x,3));
//               System.out.println(k.getPreviousBlocks().get(x).toString());
//               System.out.println(k.setBlocks(x1,3));
//               
//               System.out.println(k.getPreviousBlocks().get(x1).toString());
//
//
//               
//               System.out.println(m.toString());
//               System.out.println(k.checkRule2());
//      }

        
}